Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add strict event type checking #10235

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
Open

feat: add strict event type checking #10235

wants to merge 11 commits into from

Conversation

pskelin
Copy link
Contributor

@pskelin pskelin commented Nov 21, 2024

eventDetails field

This change is introducing a new field in the components

class MyComponent extends UI5Element {
  eventDetails!: {
    "selection-change": SelectionChangeDetails
    "delete": void
  }
}

This field doesn't have runtime semantics, it is only used to provide type information about the events that the component is firing and the corresponding types of the detail parameter.

This enables two new usages

  1. stricter type checking for event decorators and firing events
  2. future support for TSX event handler type generation

strict @event decorator

There is a new event decorator that does strict checks against this field. The old event decorator is deprecated and will be removed. To switch, simple change the import

- import event from "@ui5/webcomponents-base/dist/decorators/event.js";
+ import event from "@ui5/webcomponents-base/dist/decorators/event-strict.js";

It is no longer necessary to priovide the event type in the decorator, as TypeScript is able to infer it from the event name and the eventDetails field.

- @event<SelectionChangeDetails>("selection-change", ...)
+ @event("selection-change", ...)

strict fireDecoratorEvent

The method fireDecoratorEvent is now also checking against the eventDetails field ensuring that the event name that is fired is described and that the detail parameter is of the same type as the one in eventDetails. The event type is also inferred from the event name and no longer necessary to pass from outside.

- this.fireDecoratorEvent<SelectionChangeDetails>("selection-change", {...})
+ this.fireDecoratorEvent("selection-change", {...})

extending the eventDetails with more events

If your component extends another component and you try to add new events, you will get a TypeScript error that the new events cannot be assigned to the same field in the base class

class TimeSelectionClocks extends TimePickerInternals {
  eventDetails!: { // ts-error
    "close-picker": void,
  };

// Property 'eventDetails' in type 'TimeSelectionClocks' is not assignable to the same property in base type 'TimePickerInternals'.

In order to correctly extend the base class events, you need to add them as a type as well like this TimePickerInternals["eventDetails"]

class TimeSelectionClocks extends TimePickerInternals {
  eventDetails!: TimePickerInternals["eventDetails"] & {
    "close-picker": void,
  };

@pskelin pskelin marked this pull request as ready for review November 28, 2024 08:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants